export default {
    data() {
        return {
            //飞机的数据，用于渲染数据
            ganttData: [],

            //默认的高度
            defaultTop: 10,


            //右键菜单所需参数
            rightMenu: {
                //控制显示
                isShow: false,
                //控制位置
                left: 0,
                top: 0,
            }
        }
    },
    computed:{
        //通过选择的时间区间，得到这区间之间的数组
        choiceTimeArr() {
            let timeArr = []
            //时间戳毫秒为单位
            //尾时间-首时间 算出头尾的时间戳差  再换算成天单位                                   毫秒->分->时->天
            let diffDays = (new Date(this.choiceTime[1]).getTime() 
                            - new Date(this.choiceTime[0]).getTime())/1000/60/60/24

            //一天的时间戳
            let oneDayMs = 24*60*60*1000;
            //差了多少天就便利多少天 首时间+当前便利的天数的毫秒数
            for (let i = 0; i < diffDays+1; i++) {
                //时间戳来一个相加，得到的就是时间数组
                timeArr.push(new Date(new Date(this.choiceTime[0]).getTime() + i*oneDayMs))
            }
            return timeArr
        }
    },
    methods: {
        /**
         * 处理单条的航班的折叠
         * 这样在处理一个拖拽后的航班条的时候，就可以重新计算偏移了
         * @param flightObj 航班对象，其中包括当前对象下的航班条
         */
        handleSingleFold(flightObj,startTimeCol,endTimeCol) {
            //获得当前obj 所在数组中的index
            let index = this.ganttData.findIndex(e => e.id == flightObj.id)
            let item = flightObj.timeBlock
            //进行航班条层级计算
            this.getTier(item,1,index,startTimeCol,endTimeCol)


            //根据层级进行降序排序
            let tierItem = item.sort(this.compareByTier("DESC"))

            //通过tier做排序
            for (let i = 0; i < tierItem.length; i++) {
                //这时候每一个航班条已经获得到了层级，之后就是层级校准，让层级向上移动到最合适的位置
                this.bootTier(tierItem,tierItem[i],tierItem[i].tier,startTimeCol,endTimeCol)
            }
            this.bootTier2(tierItem)

            //重新计算最高层级
            let maxTier = item.map(e => {
                return e.tier? e.tier: 0
            })


            let maxHeight = maxTier.length > 0?Math.max(...maxTier):0

            //重叠1代表有两个   this.defaultTop * 2代表上下的空间    count * this.defaultTop 代表间距
            flightObj.height = (maxHeight+1) * 40 + this.defaultTop * 2 + maxHeight * this.defaultTop

        },
        //优化层级，让空间得到更好的利用
        bootTier(allArr,targetObj,tier,startTimeCol,endTimeCol) {

            //如果是顶层就不需要操作了
            if(tier) {
                //得到上一层级
                let lastTier = tier - 1
                //对全量数据进行排序，用于后续碰撞
                let afterSortArr = allArr.filter( e => (e.tier || 0) == lastTier).sort(this.compare(endTimeCol))

                let flag = false;
                //此次遍历的数据和afterSortArr进行碰撞计算，如果没有发生碰撞那就更换当前遍历对象的tier

                for (let j = 0; j < afterSortArr.length; j++) {

                    //一旦发生碰撞，那么就不进行tier更换
                    if ( new Date(afterSortArr[j][endTimeCol]) >= new Date(targetObj[startTimeCol] )
                        && new Date(targetObj[endTimeCol]) >= new Date(afterSortArr[j][startTimeCol])) {

                        flag = true
                    }
                }
                //执行替换
                if(!flag) {
                    //替换tier
                    targetObj.tier = lastTier

                    // 计算top + 最初顶上的高度
                    let top = 40*(lastTier) + this.defaultTop * (lastTier) + this.defaultTop
                    targetObj.top = top
                }

                this.bootTier(allArr,targetObj,lastTier,startTimeCol,endTimeCol)
            }
        },
        //优化层级2  主要处理空挡数据
        bootTier2(arr) {
            //得到所有tier的数组
            let tierArr = arr.map(e => {
                return e.tier || 0
            })
            let set = new Set(tierArr.sort())
            //升序排序 去重
            let nArr = Array.from(set)


            for (let i = 0; i < nArr.length; i++) {
                if(nArr[i]) {
                    let lastTier = nArr[i] - 1
                    //上一层的时间块数量
                    let lastArrLength = arr.filter(e => (e.tier || 0) == lastTier)
                    //说明该层级存在浪费情况
                    if(lastArrLength.length == 0) {

                        let targetArr = arr.filter(e => (e.tier || 0) == nArr[i])
                        targetArr.forEach(e => {
                            e.tier = lastTier
                            // 计算top + 最初顶上的高度
                            let top = 40*(lastTier) + this.defaultTop * (lastTier) + this.defaultTop
                            e.top = top
                        })

                        this.bootTier2(arr)
                    }
                }
            }
        },
        //生成层级  层级用于计算高度以及 当前时间块展示的位置
        getTier(origin,tier,bigIndex,startTimeCol,endTimeCol) {
            let set = new Set()
            //根据最大时间排序
            let arr = origin.sort(this.compare(endTimeCol))
            for (let i = 0; i < arr.length; i++) {
                if (arr[i + 1]) {
                    //出现重叠
                    if (new Date(arr[i][endTimeCol]) >= new Date(arr[i + 1][startTimeCol])) {
                        //重叠的添加进入set
                        set.add(arr[i + 1].id)
                    }
                }
            }
            //数组去重
            let nArr = Array.from(set)
            //需要换行的那个对象
            let objArr =  nArr.map(e => {
                let index =  origin.findIndex(i=>i.id === e)
                let obj = origin[index]
                obj.tier = tier
                return obj
            })

            //套入全局属性
            nArr.forEach((e) => {
                //全局的index
                let index =  origin.findIndex(i=>i.id === e)
                // 计算top + 最初顶上的高度
                let top = 40*(tier) + this.defaultTop * (tier) + this.defaultTop

                //全局 top
                origin[index].top = top
                //层级
                origin[index].tier = tier
            })

            if(nArr && nArr.length > 0) {
                this.getTier(objArr,tier + 1,bigIndex,startTimeCol,endTimeCol)
            }
        },
        
        //生成uuid
        generateUUID() {
            let d = new Date().getTime();
            if (window.performance && typeof window.performance.now === "function") {
                d += performance.now(); //use high-precision timer if available
            }
            let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                let r = (d + Math.random() * 16) % 16 | 0;
                d = Math.floor(d / 16);
                return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
            });
            return uuid;
        },
        //排序函数 升序
        compare(property){
            return function(a,b){
                // ab 皆为时间类型 需要转换
                let value1 = new Date(a[property]).getTime();
                let value2 = new Date(b[property]).getTime();
                return value1 - value2;
            }
        },
        //根据层级做排序 降序
        compareByTier(dir) {
            return function(a,b){
                // ab 皆为时间类型 需要转换
                let value1 = a['tier'] || 0;
                let value2 = b['tier'] || 0;

                //升序
                if(dir == 'ASC') {
                    return value1 - value2;
                }
                //降序
                else {
                    return value2 - value1;
                }
            }
        }
    }
}